package server;

import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;

import quorum.Quorum;
import utils.PrintMsg;

import common.Entity;
import common.Lists;
import common.Message;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class Server {
	static private int serverID = 0;
	static private int serverPort = 9999;
	
	static private Map<Integer, ServerThread> ServerThreads;
	
	public static void main(String[] argc) throws UnknownHostException
	{
		if(argc.length < 1)
		{
			System.out.println("Usage: ProgramName <INTEGER:ServerID>");
			return;
		}
		try
		{
			serverID = Integer.parseInt(argc[0]);
		}
		catch (Exception exception)
		{
			exception.printStackTrace();
			return;
		}
		StartUDP();
		//StartClientKick();
		//Message m = new Message("0\t\t\t9\t\t768768768\n".getBytes());
		//m.setDest(new Entity(0,InetAddress.getLocalHost().getHostAddress()));
		//ServerUDPSend.UDPSendBuffer.add(m);
		StartServer();

		
	}
	
	public static String GetIP(int sID)
	{
		Entity[] e = Lists.getInstance().getStaticServerList().toArray(new Entity[Lists.getInstance().getStaticServerList().size()]);
		for(int i = 0; i <e.length; i ++)
		{
			if(e[i].getId() == sID)
			{
				return e[i].getIp();
			}
		}
		return null;
	}
	
	public static void StartServer()
	{
		try
		{
			SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory
					.getDefault();
			SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory
					.createServerSocket(serverPort);
			final String[] enabledCipherSuites = { "SSL_DH_anon_WITH_RC4_128_MD5" };
			sslserversocket.setEnabledCipherSuites(enabledCipherSuites);
			
			
			
			Entity en = new Entity(serverID, GetIP(serverID));
			
			Quorum.create(serverID,GetIP(serverID));
			//Quorum q = new Quorum(serverID,GetIP(serverID));
			
			Lists.getInstance().addLiveServer(en);
			
			PrintMsg.PrintStatic("Server Started", "IP Address: " + GetIP(serverID));
			while (true)
			{
				SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();
				Runnable SocketThreads = new ServerThread(serverID, sslsocket, 0);
				Thread t = new Thread(SocketThreads);
				t.start();
				PrintMsg.PrintStatic("New Client", "IP Address: " + sslsocket.getInetAddress().getHostAddress());
			}
		} catch (Exception exception)
		{
			exception.printStackTrace();
		}
	}
	
	public static void StartClientKick()
	{
		ClientKicker ck = new ClientKicker(serverID);
		Thread ckThread = new Thread(ck);
		ckThread.start();
	}
	public static void StartUDP()
	{
		ServerUDPRead UDPReader = new ServerUDPRead();
		Thread UDPThread = new Thread(UDPReader);
		UDPThread.start();
		
		ServerUDPSend UDPSender = new ServerUDPSend();
		Thread UDPSenderThread = new Thread(UDPSender);
		UDPSenderThread.start();
		
		ServerUDPTimeoutListner UDPTimer = new ServerUDPTimeoutListner();
		Thread ServerUDPTimeoutListner = new Thread(UDPTimer);
		ServerUDPTimeoutListner.start();
	}
	
}
